package fr.upmc.i3s.fuglmeyeranalyser.tools;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.GeneralSecurityException;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;

import fr.upmc.i3s.fuglmeyeranalyser.tools.utils.EncryptUtils;
import fr.upmc.i3s.fuglmeyeranalyser.view.strings.StringsConstants;

public class PasswordManager {

	public static boolean askUserPassword(String pwdFile) {
		boolean customized = checkIfPasswordHasBeenCustomized(pwdFile);
		if(customized) {
			boolean success = showAskPasswordDialog(pwdFile);
			if(success) {
				return true;
			} else {
				displayMessageDialog(StringsConstants.LABEL_ERROR_PWD, StringsConstants.LABEL_WRONG_PWD);
				return false;
			}
		} else {
			char[] password = customizePassword(pwdFile);
			if(password==null) {
				displayMessageDialog(StringsConstants.LABEL_PWD_NOT_CREATED, StringsConstants.LABEL_PWD_DOESNT_MATCH);
				return false;
			} else {
				try {
					EncryptUtils.encryptPassword(pwdFile, password, 1);
					displayMessageDialog(StringsConstants.LABEL_PWD_CREATED, StringsConstants.LABEL_PWD_MATCH);
					boolean success = showAskPasswordDialog(pwdFile);
					if(success) {
						return true;
					} else {
						displayMessageDialog(StringsConstants.LABEL_ERROR_PWD, StringsConstants.LABEL_WRONG_PWD);
						return false;
					}
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (GeneralSecurityException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return false;
		}
	}
	
	public static boolean checkIfPasswordHasBeenCustomized(String file) {
		File f = new File(file);
		if(f.exists()) {
			return true;
		} else {
			return false;
		}
	}
	
	private static char[] customizePassword(String pwdFile) {
		char[] pwd1 = showCustomizePasswordDialog(StringsConstants.LABEL_CUSTOMIZE_FIRST);
		if(pwd1 == null) {
			return null;
		}
		char[] pwd2 = showCustomizePasswordDialog(StringsConstants.LABEL_CUSTOMIZE_SECOND);
		if(pwd2 == null) {
			return null;
		}
		if(!passwordMatches(pwd1, pwd2)) {
			return null;
		}
		return pwd1;
	}
	
	private static boolean passwordMatches(char[] pwd1, char[] pwd2) {
		if(pwd1==null || pwd2==null) {
			return false;
		}
		if(pwd1.length != pwd2.length) {
			return false;
		}
		for(int i=0; i<pwd1.length; i++) {
			if(!(pwd1[i]==pwd2[i])) {
				return false;
			}
		}
		return true;
	}
	
	public static char[] showCustomizePasswordDialog(String message) {
		JPanel panel = new JPanel();
		JLabel label = new JLabel(message);
		JPasswordField pass = new JPasswordField(12);
		panel.add(label);
		panel.add(pass);
		String[] options = new String[]{StringsConstants.LABEL_OK, StringsConstants.LABEL_CANCEL};
		int option = JOptionPane.showOptionDialog(null, panel, StringsConstants.LABEL_CUSTOMIZE_PWD,
		                         JOptionPane.NO_OPTION, JOptionPane.PLAIN_MESSAGE,
		                         null, options, options[1]);
		if(option == JOptionPane.OK_OPTION) { // pressing OK button
		    char[] password = pass.getPassword();
		    return password;
		} 
		return null;
	}
	
	private static boolean showAskPasswordDialog(String pwdFile) {
		JPanel panel = new JPanel();
		JLabel label = new JLabel(StringsConstants.LABEL_ENTER_CODE);
		JPasswordField pass = new JPasswordField(12);
		panel.add(label);
		panel.add(pass);
		String[] options = new String[]{StringsConstants.LABEL_OK, StringsConstants.LABEL_CANCEL};
		int option = JOptionPane.showOptionDialog(null, panel, StringsConstants.LABEL_LOCKED,
		                         JOptionPane.NO_OPTION, JOptionPane.PLAIN_MESSAGE,
		                         null, options, options[1]);
		if(option == JOptionPane.OK_OPTION) { // pressing OK button
		    char[] password = pass.getPassword();
		    boolean success = verifyUserPassword(pwdFile, password);
		    if(success) {
		    	return true;
		    } 
		} 
		return false;
	}
	
	private static boolean verifyUserPassword(String file, char[] password) {
		try {
			String pwd = EncryptUtils.decryptPassword(file);
			if(String.copyValueOf(password).equals(pwd)) {
				return true;
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (GeneralSecurityException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	private static boolean displayMessageDialog(String title, String message) {
		JPanel panel = new JPanel();
		JLabel label = new JLabel(message);
		panel.add(label);
		String[] options = new String[]{StringsConstants.LABEL_OK};
		JOptionPane.showOptionDialog(null, panel, title,
		                         JOptionPane.NO_OPTION, JOptionPane.PLAIN_MESSAGE,
		                         null, options, null);
		return true;
	}

}
